package net.huashitong.ssydt.provider.article.service;


import net.huashitong.ssydt.article.constant.ArticleConsts;
import net.huashitong.ssydt.article.entity.SsArticleArticle;
import net.huashitong.ssydt.article.entity.SsArticleCollection;
import net.huashitong.ssydt.article.entity.SsArticlePraiseRecord;
import net.huashitong.ssydt.article.entity.SsArticleType;
import net.huashitong.ssydt.article.entity.vo.*;
import net.huashitong.ssydt.exceptions.ServiceException;
import net.huashitong.ssydt.provider.comment.service.CommentService;
import net.huashitong.ssydt.provider.money.service.MoneyService;
import net.huashitong.ssydt.provider.utils.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

/**
 * @author <a href="mailto:yhy23456@163.com">huiyang.yu</a>
 * @since 2017.09.14
 */
@Service
@Transactional
public class ArticleServiceImpl implements ArticleService {

    private SsArticleArticleService ssArticleArticleService;

    private SsArticleTypeService ssArticleTypeService;

    private CommentService commentService;

    private SsArticlePraiseRecordService ssArticlePraiseRecordService;

    private SsArticleCollectionService ssArticleCollectionService;

    private MoneyService moneyService;

    @Autowired
    public ArticleServiceImpl(SsArticleArticleService ssArticleArticleService,
                              SsArticleTypeService ssArticleTypeService,
                              CommentService commentService,
                              SsArticlePraiseRecordService ssArticlePraiseRecordService,
                              MoneyService moneyService,
                              SsArticleCollectionService ssArticleCollectionService) {
        this.ssArticleArticleService = ssArticleArticleService;
        this.ssArticleTypeService = ssArticleTypeService;
        this.commentService = commentService;
        this.ssArticlePraiseRecordService = ssArticlePraiseRecordService;
        this.ssArticleCollectionService = ssArticleCollectionService;
        this.moneyService = moneyService;
    }

    @Override
    public List<ArticleListOutVO> getArticles(ArticleListInVO articleListInVO) {
        List<SsArticleArticle> ssArticleArticles = ssArticleArticleService.query(articleListInVO);
        List<ArticleListOutVO> articleListOutVOS = new ArrayList<>();
        for (SsArticleArticle ssArticleArticle : ssArticleArticles) {
            ArticleListOutVO articleListOutVO = getArticleListOutVO(ssArticleArticle);
            articleListOutVOS.add(articleListOutVO);
        }
        return articleListOutVOS;
    }

    @Override
    public List<ArticleTypeListVO> getArticleTypes() {
        List<ArticleTypeListVO> articleTypeListVOS = new ArrayList<>();
        List<SsArticleType> ssArticleTypes = ssArticleTypeService.listValidArticleTypes();
        for (SsArticleType ssArticleType : ssArticleTypes) {
            ArticleTypeListVO articleTypeListVO = new ArticleTypeListVO(ssArticleType);
            articleTypeListVOS.add(articleTypeListVO);
        }
        return articleTypeListVOS;
    }

    @Override
    public ArticleBottomVO getArticleBottom(Long articleId, String userId) {
        SsArticleArticle ssArticleArticle = ssArticleArticleService.selectByPrimaryKey(articleId);
        if (ssArticleArticle == null) {
            throw new ServiceException("文章不存在");
        }
        Integer commentsNumber = commentService.getArticleCommentsNumber(articleId);

        boolean nonEquals = !ssArticleArticle.getCommentNumber().equals(commentsNumber);
        if (nonEquals) {
            updateArticleCommentNumberAndHotNumber(ssArticleArticle, commentsNumber);
        }

        boolean isPraise = false;
        boolean isCollection = false;
        if (StringUtils.isNotBlank(userId)) {
            commentsNumber = getCommentsNumber(articleId, userId, commentsNumber);
            SsArticlePraiseRecord praiseRecord = ssArticlePraiseRecordService.getByUserIdWithArticleId(userId, articleId);
            if (praiseRecord != null) {
                isPraise = true;
            }
            SsArticleCollection ssArticleCollection = ssArticleCollectionService.getByUserIdWithArticleId(userId, articleId);
            if (ssArticleCollection != null) {
                isCollection = true;
            }
        }
        //练习权限
        boolean testAuthorization = isAuthorization(ssArticleArticle, userId);

        ArticleBottomVO articleBottomVO = new ArticleBottomVO(ssArticleArticle, commentsNumber);
        articleBottomVO.setPraise(isPraise);
        articleBottomVO.setCollection(isCollection);
        articleBottomVO.setTestAuthorization(testAuthorization);
        return articleBottomVO;
    }

    @Override
    public void postArticlePraises(Long articleId, String userId) {
        SsArticlePraiseRecord record = ssArticlePraiseRecordService.getByUserIdWithArticleId(userId, articleId);
        if (record == null) {
            record = new SsArticlePraiseRecord();
            record.setArticleId(articleId);
            record.setUserId(userId);
            ssArticlePraiseRecordService.insertSelective(record);

            ssArticleArticleService.incrementPraiseNumber(articleId);
            ssArticleArticleService.incrementHotNumber(articleId, ArticleConsts.HOT_NUMBER_PRAISE);
        }
    }

    @Override
    public void deleteArticlePraises(Long articleId, String userId) {
        SsArticlePraiseRecord record = ssArticlePraiseRecordService.getByUserIdWithArticleId(userId, articleId);
        if (record != null) {
            ssArticlePraiseRecordService.deleteByPrimaryKey(record.getId());

            ssArticleArticleService.incrementPraiseNumber(articleId, -1);
            ssArticleArticleService.incrementHotNumber(articleId, -(ArticleConsts.HOT_NUMBER_PRAISE));
        }
    }

    @Override
    public void postArticleCollections(Long articleId, String userId) {
        SsArticleCollection collection = ssArticleCollectionService.getByUserIdWithArticleId(userId, articleId);
        if (collection == null) {
            collection = new SsArticleCollection();
            collection.setArticleId(articleId);
            collection.setUserId(userId);
            ssArticleCollectionService.insertSelective(collection);
        }

    }

    @Override
    public void deleteArticleCollections(Long articleId, String userId) {
        SsArticleCollection collection = ssArticleCollectionService.getByUserIdWithArticleId(userId, articleId);
        if (collection != null) {
            ssArticleCollectionService.deleteByPrimaryKey(collection.getId());
        }
    }

    @Override
    public void deleteArticlesCollections(String userId) {
        ssArticleCollectionService.deleteByUserId(userId);
    }

    @Override
    public List<ArticleListOutVO> getArticlesCollections(CollectionsQueryVO collectionsQueryVO) {
        List<SsArticleCollection> collections = ssArticleCollectionService.queryByUserId(collectionsQueryVO);
        List<ArticleListOutVO> articleListOutVOS = new ArrayList<>();
        for (SsArticleCollection collection : collections) {
            SsArticleArticle ssArticleArticle = ssArticleArticleService.getById(collection.getArticleId());
            if (ssArticleArticle == null) {
                ArticleListOutVO articleListOutVO = new ArticleListOutVO();
                articleListOutVO.setId(collection.getArticleId());
                articleListOutVO.setTitle("此文章已被删除");
                articleListOutVOS.add(articleListOutVO);
                continue;
            }
            ArticleListOutVO articleListOutVO = getArticleListOutVO(ssArticleArticle);
            articleListOutVOS.add(articleListOutVO);
        }
        return articleListOutVOS;
    }

    /**
     * 获取文章列表输出对象
     *
     * @param ssArticleArticle
     * @return
     */
    private ArticleListOutVO getArticleListOutVO(SsArticleArticle ssArticleArticle) {
        SsArticleType ssArticleType = ssArticleTypeService.selectByPrimaryKey(ssArticleArticle.getArticleTypeId());
        String typeName = ssArticleType.getName();
        return new ArticleListOutVO(ssArticleArticle, typeName);
    }

    /**
     * 更新文章评论数和热门指数
     *
     * @param ssArticleArticle
     * @param commentsNumber
     */
    private void updateArticleCommentNumberAndHotNumber(SsArticleArticle ssArticleArticle, Integer commentsNumber) {
        int number = commentsNumber - ssArticleArticle.getCommentNumber();
        ssArticleArticleService.incrementCommentNumber(ssArticleArticle.getId(), number);
        long hotNumber = number * ArticleConsts.HOT_NUMBER_COMMENT;
        ssArticleArticleService.incrementHotNumber(ssArticleArticle.getId(), hotNumber);
    }

    /**
     * 针对用户加载动态评论数
     *
     * @param articleId
     * @param userId
     * @param commentsNumber
     * @return
     */
    private int getCommentsNumber(Long articleId, String userId, int commentsNumber) {
        int number = commentService.getArticleNonCheckPass(articleId, userId);
        return commentsNumber + number;
    }

    /**
     * 判断是否有权限（日报当天免费，其他收费）
     *
     * @param ssArticle
     * @param userId
     * @return
     */
    private boolean isAuthorization(SsArticleArticle ssArticle, String userId) {
//        if (ssArticle.getArticleTypeId().equals(3L)
//                && DateUtils.getDate().equals(ssArticle.getBelongDate())) {
//            return true;
//        }
//        if (ssArticle.getArticleTypeId().equals(3L) || ssArticle.getArticleTypeId().equals(4L)) {
//            boolean isVip = moneyService.vipMy(userId).isVip();
//            if (isVip) {
//                return true;
//            }
//        }
        if (ssArticle.getArticleTypeId().equals(3L)) {
            return true;
        }else if (ssArticle.getArticleTypeId().equals(4L)) {
            boolean isVip = moneyService.vipMy(userId).isVip();
            if (isVip) {
                return true;
            }
        }
        return false;
    }

}
